using BLToolkit.Data.Linq;
using Rsdn.Janus.DataModel;

namespace Rsdn.Janus
{
    using System;
    using System.Linq;
    using System.Windows.Forms;
    using BLToolkit.Data;

    /// <summary>
    ///   Summary description for ForumsBox.
    /// </summary>
    public class ForumsBox : ComboBox
    {
        private IServiceProvider _provider;
        private int _forumId;

        /// <summary>
        /// Initializes a new instance of the <see cref="ForumsBox"/> class.
        /// For Designer trick only!
        /// </summary>
        public ForumsBox()
        {
            Init();
        }

        public ForumsBox(IServiceProvider provider)
        {
            Provider = provider;
            Init();
        }

        private void Init()
        {
            _forumId = -1;

            InitializeComponent();

            DropDownStyle = ComboBoxStyle.DropDownList;
            MaxDropDownItems = 12;
            Items.Clear();
        }

        public int ForumId
        {
            get { return _forumId; }
        }

        /// <summary>
        /// Sets the provider.
        /// For Designer trick only!
        /// </summary>
        /// <value>The provider.</value>
        public IServiceProvider Provider
        {
            set { _provider = value; }
        }

        private void InitializeComponent()
        {
            SuspendLayout();

            // ForumsBox
            SelectedIndexChanged += ForumsBox_SelectedIndexChanged;
            ResumeLayout(false);
        }

        public void InitForumsComboBox(string desc, int selectedId)
        {
            // add top item
            Items.Add(new ForumDescrContainer(desc, -1));
            if (selectedId == -1)
            {
                SelectedIndex = 0;
            }

            InitForumsComboBox(selectedId);
        }

        /// <exception cref="System.ArgumentNullException">source or selector is null.</exception>
        public void InitForumsComboBox(int selectedForumId)
        {
            // fill combo box
			using (var mgr = _provider.CreateDBContext())
            {
                bool fullNames = Config.Instance.ForumDisplayConfig.ShowFullForumNames;
                Table<ISubscribedForum> subscribedForums = mgr.SubscribedForums();

                IQueryable<ForumDescrContainer> forumDescrContainers =
                    subscribedForums
                        .OrderBy(f => fullNames ? f.Descript : f.Name)
                        .Select(
                            f =>
                            new ForumDescrContainer(
                                fullNames ? f.Descript : f.Name,
                                f.ID)
                        );

                ForumDescrContainer[] forums = forumDescrContainers.ToArray();

                Items.AddRange(forums);

                var enumerable = forums.Select((f, i) => new {f, i});
                var sel = enumerable.FirstOrDefault(p => p.f.Id == selectedForumId);

                if (sel != null)
                {
                    SelectedIndex = sel.i;
                }
                else if (selectedForumId > 0)
                {
                    IQueryable<IServerForum> serverForums = mgr.ServerForums(f => f.ID == selectedForumId);
                    IQueryable<ForumDescrContainer> descrContainers = serverForums.Select(
                        f =>
                        new ForumDescrContainer(
                            fullNames ? f.Descript : f.Name,
                            f.ID)
                        );

                    if (descrContainers.Count() > 0)
                    {
                        forums = descrContainers.ToArray();
                        Items.AddRange(forums);
                        SelectedIndex = Items.Count - 1;
                    }
                }
            }
        }

        private void ForumsBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            object selItem = SelectedItem;
            _forumId = selItem == null ? -1 : ((ForumDescrContainer) selItem).Id;
        }
        #region ForumDescrContainer (Item container)

        private class ForumDescrContainer
        {
            private readonly int _id;
            private readonly string _name;

            public ForumDescrContainer(string name, int id)
            {
                _name = name;
                _id = id;
            }

            public int Id
            {
                get { return _id; }
            }

            public override string ToString()
            {
                return _name ?? string.Empty;
            }
        }

        #endregion
    }
}